/**
 * 
 */
package model;

import java.net.URL;
import java.util.ArrayList;
import java.util.Locale;

import javax.cim.CIMDataType;
import javax.cim.CIMInstance;
import javax.cim.CIMObjectPath;
import javax.cim.CIMProperty;
import javax.cim.UnsignedInteger32;
import javax.security.auth.Subject;
import javax.wbem.CloseableIterator;
import javax.wbem.client.PasswordCredential;
import javax.wbem.client.UserPrincipal;
import javax.wbem.client.WBEMClient;
import javax.wbem.client.WBEMClientConstants;
import javax.wbem.client.WBEMClientFactory;


/**
 * This class is the representation of the CIM server on the client side... 
 * Any operation on the server side must reference an instance of this class, directly or indirectly.
 * @author alith
 */
public class CIMServer {
	
	private String nameSpace;
	private String host;
	private String user;
	private String pwd;
	private WBEMClient client;	
	
	/////////////////
	//partie server//
	/////////////////

	/**
	 * constructor of the server
	 * @param nameSpace the namespace you want to use
	 * @param host the full url of the host
	 * @param user your login on the server
	 * @param password your password on the server
	 * @throws CIMBadArgument if a parameter is null or incorrect (exception thrown by the client...)
	 * @throws Exception an exception in the following:<br>
	 *  -> IllegalArgumentException - If the protocol CIM_XML is null or empty.<br>
     *								  If the protocol CIM_XML is not supported.<br>
     *<br>
     *  -> WBEMException - If the protocol implementation could not be loaded.<br>
     *                   - If the connection with the server is unsuccessful, one of the following status codes will be returned:<br>
     *    CIM_ERR_ACCESS_DENIED<br>
     *    CIM_ERR_NOT_SUPPORTED (implementation DOES NOT support ANY Extrinsic Method Invocation)<br>
     *    CIM_ERR_INVALID_NAMESPACE<br>
     *    CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *    CIM_ERR_NOT_FOUND (if instance does not exist)<br>
     *    CIM_ERR_METHOD_NOT_FOUND<br>
     *    CIM_ERR_METHOD_NOT_AVAILABLE<br>
     *    CIM_ERR_FAILED (some other unspecified error occurred)<br>
     *    <br>
     *  -> NullPointerException if the parameters are null
	 */
	public CIMServer(String nameSpace,String host,String user, String password) throws CIMBadArgument,Exception {//si on faisait des verifs...
		this.host = host;
		this.nameSpace = nameSpace;
		this.user = user;
		pwd = password;
		URL cimomUrl = new URL(host);
		client = WBEMClientFactory.getClient(WBEMClientConstants.PROTOCOL_CIMXML);
		CIMObjectPath path = new CIMObjectPath(cimomUrl.getProtocol(),cimomUrl.getHost(), String.valueOf(cimomUrl.getPort()), null, null, null);
		Subject subject = new Subject();
		subject.getPrincipals().add(new UserPrincipal(user));
		subject.getPrivateCredentials().add(new PasswordCredential(pwd));
		client.initialize(path, subject, Locale.getAvailableLocales());
	}
	
	/**
	 * change the server, reconnect to the new host
	 * @param newHost the full url of the new host
	 * @throws CIMBadArgument if a parameter is null or incorrect (exception thrown by the client...)
	 * @throws Exception an exception in the following:<br>
	 *  -> IllegalArgumentException - If the protocol CIM_XML is null or empty.<br>
     *								  If the protocol CIM_XML is not supported.<br>
     *<br>
     *  -> WBEMException - If the protocol implementation could not be loaded.<br>
     *                   - If the connection with the server is unsuccessful, one of the following status codes will be returned:<br>
     *    CIM_ERR_ACCESS_DENIED<br>
     *    CIM_ERR_NOT_SUPPORTED (implementation DOES NOT support ANY Extrinsic Method Invocation)<br>
     *    CIM_ERR_INVALID_NAMESPACE<br>
     *    CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *    CIM_ERR_NOT_FOUND (if instance does not exist)<br>
     *    CIM_ERR_METHOD_NOT_FOUND<br>
     *    CIM_ERR_METHOD_NOT_AVAILABLE<br>
     *    CIM_ERR_FAILED (some other unspecified error occurred)<br>
     *    <br>
     *  -> NullPointerException if the parameters are null<br>
     *	
	 */
	public void  changeServer(String newHost) throws Exception{
		host = newHost;
		URL cimomUrl = new URL(host);
		client = WBEMClientFactory.getClient(WBEMClientConstants.PROTOCOL_CIMXML);
		CIMObjectPath path = new CIMObjectPath(cimomUrl.getProtocol(),cimomUrl.getHost(), String.valueOf(cimomUrl.getPort()), null, null, null);
		Subject subject = new Subject();
		subject.getPrincipals().add(new UserPrincipal(user));
		subject.getPrivateCredentials().add(new PasswordCredential(pwd));
		client.initialize(path, subject, Locale.getAvailableLocales());
	}
	
	//////////////////////
	//partie IPSecPolicy//
	//////////////////////
	
	/**
	 * Create the fake instance of the IPSecPolicy object on the client side.
	 */
	private CIMInstance getInstance (IPSecPolicy obj) throws Exception {
		ArrayList<CIMProperty<?>> proprietes = new ArrayList<CIMProperty<?>>();
		proprietes.add(new CIMProperty<String>("source",CIMDataType.STRING_T,obj.getSource(),true,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("destination",CIMDataType.STRING_T,obj.getDestination(),true,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("protocol",CIMDataType.STRING_T,obj.getProtocol(),true,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("direction",CIMDataType.STRING_T,obj.getDirection(),true,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("action",CIMDataType.STRING_T,obj.getAction(),false,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("tunnel_in",CIMDataType.STRING_T,obj.getTunnel_in(),false,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("tunnel_out",CIMDataType.STRING_T,obj.get_tunnel_out(),false,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("type",CIMDataType.STRING_T,obj.getType(),false,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("transport_type",CIMDataType.STRING_T,obj.getTransport_type(),false,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("level",CIMDataType.STRING_T,obj.getLevel(),false,true,"IPSecPolicy"));
		CIMProperty<?>[] props = {};
		props = proprietes.toArray(props);
		return new CIMInstance(new CIMObjectPath("IPSecPolicy",nameSpace),props);
	}
	
	/**
	 * Create the path representation of the IPSecPolicy object on the client side.
	 */
	private CIMObjectPath getPath(IPSecPolicy obj) throws Exception {
		ArrayList<CIMProperty<?>> proprietes = new ArrayList<CIMProperty<?>>();
		proprietes.add(new CIMProperty<String>("source",CIMDataType.STRING_T,obj.getSource(),true,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("destination",CIMDataType.STRING_T,obj.getDestination(),true,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("protocol",CIMDataType.STRING_T,obj.getProtocol(),true,true,"IPSecPolicy"));
		proprietes.add(new CIMProperty<String>("direction",CIMDataType.STRING_T,obj.getDirection(),true,true,"IPSecPolicy"));
		CIMProperty<?>[] props = {};
		props = proprietes.toArray(props);
		return new CIMObjectPath("IPSecPolicy",nameSpace,props);
	}

	/**
	 * a fake constructor of an IPSecPolicy object
	 * @return an empty IPSecPolicy
	 * @throws CIMBadArgument if there is a bad parameter, there is no parameter, so this is never thrown.
	 */
	public IPSecPolicy newIPSecPolicy() throws CIMBadArgument{
		return new IPSecPolicy(this);		
	}
	
	/**
	 * create a new instance of IPSecPolicy, and registers it into the server
	 * @param name the name of the IPSecPolicy, not saved in the cimserver
	 * @param source the source of the IPSecPolicy,
	 * @param destination the destination of the IPSecPolicy,
	 * @param protocol the protocol of the IPSecPolicy,
	 * @param direction the direction of the IPSecPolicy,
	 * @param action the action of the IPSecPolicy,
	 * @param tunnel_in the tunnel_in of the IPSecPolicy,
	 * @param tunnel_out the tunnel_out of the IPSecPolicy,
	 * @param type the type of the IPSecPolicy,
	 * @param transport_type the transport_type of the IPSecPolicy,
	 * @param level the level of the IPSecPolicy,
	 * @return a new instance of IPSecPolicy, registered in this server
	 * @throws CIMBadArgument if an argument is null, or incorrect (verification on the client side)
     * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code  will be included:<br>
     *     CIM_ERR_ACCESS_DENIED<br>
     *     CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
     *     CIM_ERR_INVALID_NAMESPACE<br>
     *     CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *     CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *     CIM_ERR_ALREADY_EXISTS<br>
     *     CIM_ERR_FAILED (some other unspecified error occurred)<br>
     *     <br>
     *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer)
	 */
	public IPSecPolicy newIPSecPolicy(String name,String source, String destination, String protocol, String direction, String action, String tunnel_in, String tunnel_out, String type, String transport_type, String level) throws CIMBadArgument,Exception {
		IPSecPolicy result = new IPSecPolicy(name, source, destination, protocol, direction, action, tunnel_in, tunnel_out, type, transport_type, level, this);
		register(result);
		return result;
	}
	
	/**
	 * register the IPSecPolicy into this server.
	 * @param obj the IPSecPolicy to register
	 * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code  will be included:<br>
     *     CIM_ERR_ACCESS_DENIED<br>
     *     CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
     *     CIM_ERR_INVALID_NAMESPACE<br>
     *     CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *     CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *     CIM_ERR_ALREADY_EXISTS<br>
     *     CIM_ERR_FAILED (some other unspecified error occurred)<br>
     *     <br>
     *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer)
	 */
	public void register(IPSecPolicy obj) throws Exception {
		client.createInstance(getInstance(obj));
	}
	
	/**
	 * delete the instance of the IPSecpolicy corresponding to this object on the server
	 * @param obj the IPSecPolicy to delete
	 * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code will be included:<br>
     *    CIM_ERR_ACCESS_DENIED<br>
     *    CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
     *    CIM_ERR_INVALID_NAMESPACE<br>
     *    CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *    CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *    CIM_ERR_NOT_FOUND (if the instance does not exist)<br>
     *    CIM_ERR_FAILED (some other unspecified error occurred)<br>
 	 *<br>
 	 *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer) 
	 */
	public void remove(IPSecPolicy obj) throws Exception {
		client.deleteInstance(getPath(obj));
	}
	
	/**
	 * update the instance of the IPSecpolicy corresponding to this object on the server... the keys must not be empty or null.
	 * @param obj the IPSecPolicy to modify
	 * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code will be included:<br>
 	 *     CIM_ERR_ACCESS_DENIED<br>
	 *     CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
 	 *     CIM_ERR_INVALID_NAMESPACE<br>
	 *     CIM_ERR_INVALID_PARAMETER (for this method)<br>
 	 *     CIM_ERR_INVALID_CLASS (in this namespace)<br>
 	 *     CIM_ERR_NOT_FOUND (if instance does not exist)<br>
	 *     CIM_ERR_NO_SUCH_PROPERTY (in this instance)<br>
 	 *     CIM_ERR_FAILED (some other unspecified error occurred)<br>
 	 *<br>
 	 *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer) 
	 */
	public void update(IPSecPolicy obj) throws Exception {
		String[] props = {"action","tunnel_in","tunnel_out","type","transport_type","level"};
		client.modifyInstance(getInstance(obj), props);
	}
	
	/**
	 * enumerate the IPSecPolicy instances registered in this server.
	 * @return an arrayList containing the IPSecPolicy instances registered in this server.
	 * @throws ExceptionException this exception can be: <br>
	 *  ->    a WBEMException - If unsuccessful, one of the following status codes must be returned. The ORDERED list is:<br>
     *    CIM_ERR_ACCESS_DENIED<br>
     *    CIM_ERR_NOT_SUPPORTED<br>
     *    CIM_ERR_INVALID_NAMESPACE<br>
     *    CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *    CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *    CIM_ERR_FAILED (some other unspecified error occurred)  <br>   
	 */
	public ArrayList<IPSecPolicy>  enumIPSecPolicy() throws Exception{
		ArrayList<IPSecPolicy> result = new ArrayList<IPSecPolicy>();
		final CloseableIterator<CIMInstance> iterator = client.enumerateInstances(new CIMObjectPath("IPSecPolicy", nameSpace),
																				 false,false,false,null);
		int numero = 0;
		while (iterator.hasNext()) {
		      final CIMInstance inst = iterator.next(); //XXX si l'iterator renvoie une exception CIM... Not handled.
		      result.add(new IPSecPolicy(inst,numero,this));
		      numero++;
		}
		iterator.close();
		return result;		
	}
	
	////////////////////
	//partie IPSecRule//
	////////////////////
	
	/**
	 * Create the fake instance of the IPSecRule object on the client side.
	 */
	private CIMInstance getInstance (IPSecRule obj) throws Exception {
		ArrayList<CIMProperty<?>> proprietes = new ArrayList<CIMProperty<?>>();
		proprietes.add(new CIMProperty<String>("source",CIMDataType.STRING_T,obj.getSource(),true,true,"IPSecRule"));
		proprietes.add(new CIMProperty<String>("destination",CIMDataType.STRING_T,obj.getDestination(),true,true,"IPSecRule"));
		proprietes.add(new CIMProperty<String>("type",CIMDataType.STRING_T,obj.getType(),true,true,"IPSecRule"));
		proprietes.add(new CIMProperty<String>("transport_type",CIMDataType.STRING_T,obj.getTransport_type(),false,true,"IPSecRule"));
		proprietes.add(new CIMProperty<String>("spi",CIMDataType.STRING_T,obj.getSpi(),true,true,"IPSecRule"));
		proprietes.add(new CIMProperty<String>("algo",CIMDataType.STRING_T,obj.getAlgorythm(),false,true,"IPSecRule"));
		proprietes.add(new CIMProperty<String>("key",CIMDataType.STRING_T,obj.getKey(),false,true,"IPSecRule"));
		CIMProperty<?>[] props = {};
		props = proprietes.toArray(props);
		return new CIMInstance(new CIMObjectPath("IPSecRule",nameSpace),props);
	}
	
	/**
	 * Create the path representation of the IPSecRule object on the client side.
	 */
	private CIMObjectPath getPath(IPSecRule obj) throws Exception {
		ArrayList<CIMProperty<?>> proprietes = new ArrayList<CIMProperty<?>>();
		proprietes.add(new CIMProperty<String>("source",CIMDataType.STRING_T,obj.getSource(),true,true,"IPSecRule"));
		proprietes.add(new CIMProperty<String>("destination",CIMDataType.STRING_T,obj.getDestination(),true,true,"IPSecRule"));
		proprietes.add(new CIMProperty<String>("type",CIMDataType.STRING_T,obj.getType(),true,true,"IPSecRule"));
		proprietes.add(new CIMProperty<String>("spi",CIMDataType.STRING_T,obj.getSpi(),true,true,"IPSecRule"));
		CIMProperty<?>[] props = {};
		props = proprietes.toArray(props);
		return new CIMObjectPath("IPSecRule",nameSpace,props);		
	}
	
	/**
	 * a fake constructor of an IPSecPolicy object
	 * @return an empty IPSecPolicy
	 * @throws CIMBadArgument if there is a bad parameter, there is no parameter, so this is never thrown.
	 */
	public IPSecRule newIPSecRule() throws CIMBadArgument{
		return new IPSecRule(this);		
	}
	
	/**
	 * create a new instance of IPSecRule, and registers it into the server
	 * @param name the name of the IPSecRule, not stored on the server.
	 * @param source the source of the IPSecRule
	 * @param destination the destination of the IPSecRule
	 * @param type the type of the IPSecRule
	 * @param transport_type the transport_type of the IPSecRule
	 * @param spi the spi of the IPSecRule
	 * @param algorythm the algorithm of the IPSecRule
	 * @param key the key of the IPSecRule
	 * @return a new instance of IPSecPolicy, registered in this server
	 * @throws CIMBadArgument if an argument is null, or incorrect (verification on the client side)
     * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code  will be included:<br>
     *     CIM_ERR_ACCESS_DENIED<br>
     *     CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
     *     CIM_ERR_INVALID_NAMESPACE<br>
     *     CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *     CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *     CIM_ERR_ALREADY_EXISTS<br>
     *     CIM_ERR_FAILED (some other unspecified error occurred)<br>
     *     <br>
     *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer)
	 */
	public IPSecRule newIPSecRule(String name,String source, String destination, String type, String transport_type, String spi, String algorythm, String key) throws CIMBadArgument,Exception {
		IPSecRule result = new IPSecRule(name, source, destination, type, transport_type, spi, algorythm, key,this);
		register(result);
		return result;
	}
	
	/**
	 * register the IPSecRule into this server.
	 * @param obj the IPSecRule to register
	 * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code  will be included:<br>
     *     CIM_ERR_ACCESS_DENIED<br>
     *     CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
     *     CIM_ERR_INVALID_NAMESPACE<br>
     *     CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *     CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *     CIM_ERR_ALREADY_EXISTS<br>
     *     CIM_ERR_FAILED (some other unspecified error occurred)<br>
     *     <br>
     *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer)
	 */
	public void register(IPSecRule obj) throws Exception {
		client.createInstance(getInstance(obj));
	}
	
	/**
	 * delete the instance of the IPSecRule corresponding to this object on the server
	 * @param obj the IPSecRule to delete
	 * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code will be included:<br>
     *    CIM_ERR_ACCESS_DENIED<br>
     *    CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
     *    CIM_ERR_INVALID_NAMESPACE<br>
     *    CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *    CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *    CIM_ERR_NOT_FOUND (if the instance does not exist)<br>
     *    CIM_ERR_FAILED (some other unspecified error occurred)<br>
 	 *<br>
 	 *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer) 
	 */
	public void remove(IPSecRule obj) throws Exception {
		client.deleteInstance(getPath(obj));
	}
	
	/**
	 * update the instance of the IPSecRule corresponding to this object on the server... the keys must not be empty or null.
	 * @param obj the IPSecRule to modify
	 * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code will be included:<br>
 	 *     CIM_ERR_ACCESS_DENIED<br>
	 *     CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
 	 *     CIM_ERR_INVALID_NAMESPACE<br>
	 *     CIM_ERR_INVALID_PARAMETER (for this method)<br>
 	 *     CIM_ERR_INVALID_CLASS (in this namespace)<br>
 	 *     CIM_ERR_NOT_FOUND (if instance does not exist)<br>
	 *     CIM_ERR_NO_SUCH_PROPERTY (in this instance)<br>
 	 *     CIM_ERR_FAILED (some other unspecified error occurred)<br>
 	 *<br>
 	 *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer) 
	 */
	public void update(IPSecRule obj) throws Exception {
		String[] props = {"transport_type","algo","key"};	
		client.modifyInstance(getInstance(obj), props);
	}
	
	/**
	 * enumerate the IPSecRule instances registered in this server.
	 * @return an arrayList containing the IPSecRule instances registered in this server.
	 * @throws ExceptionException this exception can be: <br>
	 *  ->    a WBEMException - If unsuccessful, one of the following status codes must be returned. The ORDERED list is:<br>
     *    CIM_ERR_ACCESS_DENIED<br>
     *    CIM_ERR_NOT_SUPPORTED<br>
     *    CIM_ERR_INVALID_NAMESPACE<br>
     *    CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *    CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *    CIM_ERR_FAILED (some other unspecified error occurred)    <br> 
	 */
	public ArrayList<IPSecRule>  enumIPSecRule() throws Exception{
		ArrayList<IPSecRule> result = new ArrayList<IPSecRule>();
		final CloseableIterator<CIMInstance> iterator = client.enumerateInstances(new CIMObjectPath("IPSecRule", nameSpace),
																				 false,false,false,null);
		int numero = 0;
		while (iterator.hasNext()) {
		      final CIMInstance inst = iterator.next();//XXX si l'iterator renvoie une exception CIM... Not handled.
		      result.add(new IPSecRule(inst,numero,this));
		      numero++;
		}
		iterator.close();
		return result;		
	}
	
	//////////////////////
	//partie IPTableRule//
	//////////////////////	

	/**
	 * Create the fake instance of the IPTableRule object on the client side.
	 */
	private CIMInstance getInstance (IPTableRule obj) throws Exception {
		ArrayList<CIMProperty<?>> proprietes = new ArrayList<CIMProperty<?>>();
		proprietes.add(new CIMProperty<UnsignedInteger32>("id",CIMDataType.UINT32_T,obj.getUnsignedId(),false,true,"Iptables"));
		proprietes.add(new CIMProperty<String>("chain",CIMDataType.STRING_T,obj.getChain(),false,true,"Iptables"));
		proprietes.add(new CIMProperty<String>("source",CIMDataType.STRING_T,obj.getSource(),false,true,"Iptables"));
		proprietes.add(new CIMProperty<String>("destination",CIMDataType.STRING_T,obj.getDestination(),false,true,"Iptables"));
		proprietes.add(new CIMProperty<String>("protocol",CIMDataType.STRING_T,obj.getProtocol(),false,true,"Iptables"));
		proprietes.add(new CIMProperty<String>("sourcePort",CIMDataType.STRING_T,obj.getSource_port(),false,true,"Iptables"));
		proprietes.add(new CIMProperty<String>("destinationPort",CIMDataType.STRING_T,obj.getDestination_port(),false,true,"Iptables"));
		proprietes.add(new CIMProperty<String>("jump",CIMDataType.STRING_T,obj.getJump(),false,true,"Iptables"));
		CIMProperty<?>[] props = {};
		props = proprietes.toArray(props);
		return new CIMInstance(new CIMObjectPath("Iptables",nameSpace),props);
	}
	
	/**
	 * Create the path representation of the IPSecRule object on the client side.
	 */
	private CIMObjectPath getPath(IPTableRule obj) throws Exception {
		ArrayList<CIMProperty<?>> proprietes = new ArrayList<CIMProperty<?>>();
		proprietes.add(new CIMProperty<UnsignedInteger32>("id",CIMDataType.UINT32_T,obj.getUnsignedId(),false,true,"Iptables"));
		CIMProperty<?>[] props = {};
		props = proprietes.toArray(props);
		return new CIMObjectPath("Iptables",nameSpace,props);
	}
	
	/**
	 * a fake constructor of an IPTableRule object
	 * @return an empty IPTableRule
	 * @throws CIMBadArgument if there is a bad parameter, there is no parameter, so this is never thrown.
	 */
	public IPTableRule newIPTableRule() throws CIMBadArgument{
		return new IPTableRule(this);		
	}

	/**
	 * create a new instance of IPTableRule, and registers it into the server
	 * @param name the name of the IPTableRule, not stored on the server.
	 * @param chain the chain of the IPTableRule
	 * @param source the source of the IPTableRule
	 * @param destination the destination of the IPTableRule
	 * @param protocol the protocol of the IPTableRule
	 * @param source_port the source_port of the IPTableRule
	 * @param destination_port the destination_port of the IPTableRule
	 * @param jump the jump of the IPTableRule
	 * @return a new instance of IPTableRule, registered in this server
	 * @throws CIMBadArgument if an argument is null, or incorrect (verification on the client side)
     * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code  will be included:<br>
     *     CIM_ERR_ACCESS_DENIED<br>
     *     CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
     *     CIM_ERR_INVALID_NAMESPACE<br>
     *     CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *     CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *     CIM_ERR_ALREADY_EXISTS<br>
     *     CIM_ERR_FAILED (some other unspecified error occurred)<br>
     *     <br>
     *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer)
	 */
	public IPTableRule newIPTableRule(String name,String chain, String source, String destination, String protocol, String source_port, String destination_port, String jump) throws CIMBadArgument,Exception {
		IPTableRule result = new IPTableRule(name, chain, source, destination, protocol, source_port, destination_port, jump, this);
		register(result);
		return result;
	}
	
	/**
	 * register the IPTableRule into this server.
	 * @param obj the IPTableRule to register
	 * @throws Exception this exception can be: 
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code  will be included:<br>
     *     CIM_ERR_ACCESS_DENIED<br>
     *     CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
     *     CIM_ERR_INVALID_NAMESPACE<br>
     *     CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *     CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *     CIM_ERR_ALREADY_EXISTS<br>
     *     CIM_ERR_FAILED (some other unspecified error occurred)<br>
     *     <br>
     *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer)
	 */
	public void register(IPTableRule obj) throws Exception {
		client.createInstance(getInstance(obj));
	}
	
	/**
	 * delete the instance of the IPTableRule corresponding to this object on the server
	 * @param obj the IPTableRule to delete
	 * @throws Exception this exception can be: 
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code will be included:<br>
     *    CIM_ERR_ACCESS_DENIED<br>
     *    CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
     *    CIM_ERR_INVALID_NAMESPACE<br>
     *    CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *    CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *    CIM_ERR_NOT_FOUND (if the instance does not exist)<br>
     *    CIM_ERR_FAILED (some other unspecified error occurred)<br>
 	 *<br>
 	 *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer) 
	 */
	public void remove(IPTableRule obj) throws Exception {
		client.deleteInstance(getPath(obj));
	}
	
	/**
	 * update the instance of the IPTableRule corresponding to this object on the server... the keys must not be empty or null.
	 * @param obj the IPTableRule to modify
	 * @throws Exception this exception can be: <br>
	 *  -> a WBEMException - If the operation is unsuccessful, one of the following status code will be included:<br>
 	 *     CIM_ERR_ACCESS_DENIED<br>
	 *     CIM_ERR_NOT_SUPPORTED (provider does not support this method)<br>
 	 *     CIM_ERR_INVALID_NAMESPACE<br>
	 *     CIM_ERR_INVALID_PARAMETER (for this method)<br>
 	 *     CIM_ERR_INVALID_CLASS (in this namespace)<br>
 	 *     CIM_ERR_NOT_FOUND (if instance does not exist)<br>
	 *     CIM_ERR_NO_SUCH_PROPERTY (in this instance)<br>
 	 *     CIM_ERR_FAILED (some other unspecified error occurred)<br>
 	 *<br>
 	 *  -> an IllegalArgumentException - If the object has not all the required parameters (null).. during the creation of the
     *  instance object (on the client computer) 
	 */
	public void update(IPTableRule obj) throws Exception {
		String[] props = {"chain","source","destination","protocol","sourcePort","destinationPort","jump"};		
		client.modifyInstance(getInstance(obj), props);
	}
	
	/**
	 * enumerate the IPSecPolicy instances registered in this server.
	 * @return an arrayList containing the IPSecPolicy instances registered in this server.
	 * @throws ExceptionException this exception can be: <br>
	 *  ->    a WBEMException - If unsuccessful, one of the following status codes must be returned. The ORDERED list is:<br>
     *    CIM_ERR_ACCESS_DENIED<br>
     *    CIM_ERR_NOT_SUPPORTED<br>
     *    CIM_ERR_INVALID_NAMESPACE<br>
     *    CIM_ERR_INVALID_PARAMETER (for this method)<br>
     *    CIM_ERR_INVALID_CLASS (in this namespace)<br>
     *    CIM_ERR_FAILED (some other unspecified error occurred) <br>    
	 */
	public ArrayList<IPTableRule>  enumIPTableRule() throws Exception{	
		ArrayList<IPTableRule> result = new ArrayList<IPTableRule>();
		final CloseableIterator<CIMInstance> iterator = client.enumerateInstances(new CIMObjectPath("Iptables", nameSpace),
				 false,false,false,null);
		while (iterator.hasNext()) {
			final CIMInstance inst = iterator.next();//XXX si l'iterator renvoie une exception CIM... Not handled.
			result.add(new IPTableRule(inst,this));
		}
		iterator.close();
		return result;	
	}
}
